#include "path.h"

namespace sleek
{
    namespace core
    {
        namespace math
        {
            template<typename T> path<T>::path()
            {
                loop = false;
            }
            template<typename T> path<T>::~path()
            {
                lisp.clear();
            }

            template<typename T> void path<T>::add(vector2d<T> a)
            {
                lisp.push_back(a);
                box.addInternalPoint(a);
            }
            template<typename T> void path<T>::rmv(u32 i)
            {
                lisp.erase(i);
                recalculateBoundingBox();
            }

            template<typename T> aabbox2d<T> path<T>::getBox()
            {
                return box;
            }
            template<typename T> void path<T>::scale(vector2d<T> a)
            {
                scale(0, lisp.size(), a);
            }
            template<typename T> void path<T>::simplify(f32 factor)
            {
                simplify(0, lisp.size(), factor);
            }
            template<typename T> void path<T>::smooth(f32 factor)
            {
                smooth(0, lisp.size(), factor);
            }
            template<typename T>  vector2d<T> path<T>::getDistance()
            {
                return getDistance(0, lisp.size());
            }

            template<typename T> void path<T>:: curve(PATH_CURVE_STYLE i, f32 factor)
            {
                switch(i)
                {
                    case PCS_BEZIER:
                        for(u32 i = 0; i<lisp.size(); ++i)
                        {
                        }
                    break;
                    default: break;
                };
                removeDouble();
            }

            template<typename T> void path<T>::simplify(u32 start, u32 end, f32 factor)
            {
                if(start > lisp.size()) start = lisp.size()-1;
                if(end > lisp.size()) end = lisp.size();
            }
            template<typename T> void path<T>::smooth(u32 start, u32 end, f32 factor)
            {
                if(start > lisp.size()) start = lisp.size()-1;
                if(end > lisp.size()) end = lisp.size();
            }
            template<typename T> void path<T>::scale(u32 start, u32 end, vector2d<T>)
            {
                if(start > lisp.size()) start = lisp.size()-1;
                if(end > lisp.size()) end = lisp.size();
            }
            template<typename T> aabbox2d<T> path<T>::getBox(u32 start, u32 end)
            {
                if(start > lisp.size()) start = lisp.size()-1;
                if(end > lisp.size()) end = lisp.size();

                aabbox2d<T> tbox;
                for(u32 i = start; i<end; ++i)
                    tbox.addInternalPoint(lisp[i]);
                return tbox;
            }
            template<typename T>  vector2d<T> path<T>::getDistance(u32 start, u32 end)
            {
                if(start > lisp.size()) start = lisp.size()-1;
                if(end > lisp.size()) end = lisp.size();

                float dest = 0.f;
                for(u32 i = start; i<end-1; ++i) dest += lisp[i].getDistance(lisp[i+1]);
                return dest;
            }

            template<typename T> void path<T>::setLoop(bool i)
            {
                loop = i;
            }
            template<typename T> bool path<T>::isLoop()
            {
                return loop;
            }

            template<typename T> void path<T>::render(texture::draw *a)
            {
                for(u32 i = 0; i<lisp.size()-1; ++i)
                    a->drawLine(lisp[i], lisp[i+1]);
            }
            template<typename T> void path<T>::merge(path<T> other)
            {
                for(u32 i = 0; i<other.lisp.size(); ++i)
                    add(other.list[i]);
            }
            template<typename T> void path<T>::removeDouble()
            {
                for(u32 i = 0; i<lisp.size(); ++i)
                {
                    for(u32 a = 0; a<lisp.size(); ++a)
                    {
                        if(lisp[i] == lisp[a] && i != a)
                            lisp.erase(i);
                    }
                }
            }
            template<typename T> void path<T>::recalculateBoundingBox()
            {
                box.clear();
                for(u32 i = 0; i<lisp.size(); ++i)
                    box.addInternalPoint(lisp[i]);
            }
        }
    }
}
